/**
 * Copyright (c) 2015 www.smarthome.com All rights reserved. <br />
 * 本软件源代码版权归xxxx公司,未经许可不得任意复制与传播.<br />
 *
 */
package com.smarthome.core.user.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import com.smarthome.base.service.ShUserResourceService;
import com.smarthome.base.service.ShUserRoleResourceService;
import com.smarthome.base.service.ShUserRoleService;
import com.smarthome.common.tools.TreeUtil;
import com.smarthome.core.user.UserRoleService;
import com.smarthome.domain.bean.ShUser;
import com.smarthome.domain.bean.ShUserResource;
import com.smarthome.domain.bean.ShUserRole;
import com.smarthome.domain.bean.ShUserRoleResource;
import com.smarthome.domain.enums.ShUserSuperFlagEnum;
import com.smarthome.domain.vo.boss.Tree;

@Service("userRoleService")
public class UserRoleServiceImpl implements UserRoleService {

    protected static Logger LOGGER;

    @Resource
    private ShUserRoleService shUserRoleService;
    @Resource
    private ShUserRoleResourceService shUserRoleResourceService;
    @Resource
    private ShUserResourceService shUserResourceService;

    public UserRoleServiceImpl() {
        LOGGER = LoggerFactory.getLogger(this.getClass());
    }

	@Override
	public List<ShUserRole> queryPropertyRolesByRole(ShUserRole shUserRole) {
		//  ShUserRole shUserRole = new ShUserRole();
		if(null == shUserRole){
			shUserRole = new ShUserRole();
		}
        shUserRole.setOrderField("sortWeight");
        shUserRole.setOrderFieldType("ASC");
        return addShUserRolesResources(shUserRoleService.selectEntryList(shUserRole));
	}
    
    @Override
    public List<ShUserRole> queryAllPropertyRoles() {
        ShUserRole shUserRole = new ShUserRole();
        shUserRole.setOrderField("sortWeight");
        shUserRole.setOrderFieldType("ASC");
        return addShUserRolesResources(shUserRoleService.selectEntryList(shUserRole));
    }
    
    /**
     * @title 封装转换roles 对象
     * @createTime 2015年9月23日 上午11:11:18
     * @author dhc
     */
    @Override
    public List<ShUserRole> addShUserRolesResources(List<ShUserRole> roles){
    	if(null == roles){
    		return roles;
    	}
    	Long[] roleids = new Long[roles.size()];
    	for(int i=0 ; i<roles.size();i++){
    		roleids[i] = roles.get(i).getId();
    	}
    	List<ShUserRoleResource> urrs =  shUserRoleResourceService.selectEntryListByRoleId(roleids);
    	if(null == urrs || urrs.size() == 0){
    		return roles;    		
    	}
    	List<ShUserResource> shUserResources = shUserResourceService.queryAllOpenedUserResources();
    	if( null == shUserResources || shUserResources.size() == 0) return roles;
    	
    	Map<Long,ShUserRoleResource> urrMap = new HashMap<Long,ShUserRoleResource>();
    	Map<Long,ShUserResource> urMap = new HashMap<Long,ShUserResource>();
    	
    	for(ShUserRoleResource urr : urrs){
    		urrMap.put(urr.getId(), urr);
    	}
    	for(ShUserResource resource : shUserResources){
    		urMap.put(resource.getId(), resource);
    	}
    	
    	
    	for(ShUserRole role : roles){
    		String resourceIids = "";
    		String resourceNames = "";
    		for(ShUserRoleResource urr : urrs){
    			if(role.getId().equals(urr.getRoleId())){
    				ShUserResource resource = urMap.get(urrMap.get(urr.getId()).getResourceId());
    				if(null == resource) continue;
    				
    				if(!"".equals(resourceIids)){
    					resourceIids +=",";
    					resourceNames +=",";
    				} 
    				resourceIids += resource.getId();
    				resourceNames += resource.getName();
    			}
    		}
    		role.setResourceIds(resourceIids);
    		role.setResourceNames(resourceNames);
    	}
    	
    	return roles;
    }
    

    @Override
    public ShUserRole queryPropertyRoleById(Long id) {
        ShUserRole shUserRole = shUserRoleService.selectEntryById(id);
        if (null != shUserRole.getParentId() && 0L != shUserRole.getParentId()) {
            ShUserRole shPropertyRoleParent = shUserRoleService.selectEntryById(shUserRole.getParentId());
            shUserRole.setParentShRole(shPropertyRoleParent);
        }
        ShUserRoleResource shUserRoleResource = new ShUserRoleResource();
        shUserRoleResource.setRoleId(id);
        List<ShUserRoleResource> shPropertyRoleResources = shUserRoleResourceService.selectEntryList(shUserRoleResource);
        if (null == shPropertyRoleResources || 0 == shPropertyRoleResources.size())
            return shUserRole;
        List<ShUserResource> shUserResources = shUserResourceService.queryAllOpenedUserResources();
        Map<Long, ShUserResource> rssMap = new HashMap<Long, ShUserResource>();
        for (ShUserResource sr : shUserResources) {
            rssMap.put(sr.getId(), sr);
        }
        String ids = "";
        String names = "";
        boolean b = false;
        for (ShUserRoleResource tr : shPropertyRoleResources) {
            if (b) {
                ids += ",";
                names += ",";
            } else {
                b = true;
            }
            ids += tr.getResourceId();
            ShUserResource res =  rssMap.get(tr.getResourceId());
            if(null != res){
            	names += res.getName();
            }
        }
        shUserRole.setResourceIds(ids);
        shUserRole.setResourceNames(names);
        return shUserRole;
    }

    @Override
    public List<ShUserRole> queryPropertyRolesByUserId(Long userId) {
        return shUserRoleService.queryUserRolesByUserId(userId);
    }

    @Override
    public List<Tree> tree(ShUser shUser) {
        List<ShUserRole> currentShPropertyRoles = new ArrayList<ShUserRole>();
        if (null == shUser || (shUser.getSuperFlag() == ShUserSuperFlagEnum.SUPER.getFlag())) {// 超级管理员默认拥有所有操作权限
            currentShPropertyRoles = queryAllPropertyRoles();
        } else {
            currentShPropertyRoles = queryPropertyRolesByUserId(shUser.getId());
        }
        return generateRolesTree(currentShPropertyRoles, 0L);
    }

    private List<Tree> generateRolesTree(List<ShUserRole> shPropertyRoles, Long parentId) {
        List<Tree> trs = new ArrayList<Tree>();
        for (ShUserRole shUserRole : shPropertyRoles) {
            if (parentId == shUserRole.getParentId()) {
                Tree tr = new Tree();
                tr.setPid(shUserRole.getParentId());
                tr.setIconCls("");
                tr.setText(shUserRole.getName());
                Map<String, Object> attr = new HashMap<String, Object>();
                attr.put("url", "");
                tr.setAttributes(attr);
                tr.setChildren(generateRolesTree(shPropertyRoles, shUserRole.getId()));
                trs.add(tr);
            }
        }
        return trs;
    }

    @Override
    public List<ShUserRole> treeGrid(ShUser shUser,ShUserRole role) {
        List<ShUserRole> currentShPropertyRoles = new ArrayList<ShUserRole>();
        if (null == shUser || (shUser.getSuperFlag() == ShUserSuperFlagEnum.SUPER.getFlag())) {// 超级管理员默认拥有所有操作权限
            currentShPropertyRoles = queryPropertyRolesByRole(role);
        } else {
            currentShPropertyRoles = queryPropertyRolesByUserId(shUser.getId());
        }

        List<ShUserRole> allShPropertyRoles = queryAllPropertyRoles();
        Map<Long, ShUserRole> rsMap = new HashMap<Long, ShUserRole>();
        for (ShUserRole rs : allShPropertyRoles) {
            rsMap.put(rs.getId(), rs);
        }
        for (ShUserRole rs : currentShPropertyRoles) {
            if (null != rs.getParentId() && 0L != rs.getParentId()) {
                rs.setParentShRole(rsMap.get(rs.getParentId()));
            }
        }
        return currentShPropertyRoles;
    }

    @Override
    public void edit(ShUserRole role) {
        ShUserRole shUserRole = shUserRoleService.selectEntryById(role.getId());
        // 角色小区不能修改
        if(null == shUserRole || null ==role.getResidenceId() || !role.getResidenceId().equals(shUserRole.getResidenceId())){
        	return ;
        }
        if (shUserRole != null) {
            // TODO 需要判断当前角色是否修改到当前角色的子/孙子角色下
            BeanUtils.copyProperties(role, shUserRole);
            shUserRoleService.saveOrUpdate(shUserRole);
            //修改 资源 - 角色 对照关系
            updateUserRoleResource(shUserRole,true);
        }
    }
    
    /***
     * @title 更新角色和资源对照表
     * @createTime 2015年9月21日 下午2:50:12
     * @author dhc
     */
    private void updateUserRoleResource(ShUserRole role,boolean isEdit){
    	   Long roleId = role.getId();
           if(null != roleId  && null != role.getResourceIds() && role.getResourceIds().matches("^[0-9]+(,[0-9]+)*$") ){
           	//删除角色资源对照表
        	 if(isEdit)    	shUserRoleResourceService.deleteByRoleId(roleId);
           	String[] resourceIdStr = role.getResourceIds().split(",");
           	ShUserRoleResource[] roleresources = new ShUserRoleResource[resourceIdStr.length];
           	for(int i=0;i< resourceIdStr.length;i++){
           		String s = resourceIdStr[i];
           		ShUserRoleResource r = new ShUserRoleResource();
           		r.setRoleId(roleId);
           		r.setResourceId(new Long (s));
           		roleresources[i]  = r;
           	}
           	
           	shUserRoleResourceService.insert(roleresources);
           }
    }

    @Override
    public void add(ShUserRole role) {
      //  shUserRoleService.saveOrUpdate(role);
        // TODO 由于当前用户所属的角色，没有访问新添加的角色，所以在新添加角色的时候，将当前角色授权给当前用户的所有角色，以便添加角色后在角色列表中能够找到
        //添加角色资源对照表
        shUserRoleService.insert(role);
        //role.setId(shUserResourceService.lastSequence());
        updateUserRoleResource(role,false);
        
    }

    @Override
    public void delete(Long id) {
        List<ShUserRole> allShPropertyRoles = queryAllChildrens(queryAllPropertyRoles(), id);
        List<Long> ids = new ArrayList<Long>();
        for (ShUserRole sr : allShPropertyRoles)
            ids.add(sr.getId());
        ids.add(id);
        Long[] roleids = ids.toArray(new Long[ids.size()]);
        shUserRoleService.deleteByIds(roleids);
        // TODO 删除用户角色对照和角色资源对照记录
        shUserRoleResourceService.deleteByRoleId(roleids);
    }

    
    @Override
    public void grant(ShUserRole role) {
    	updateUserRoleResource(role,true);
    }

    private List<ShUserRole> queryAllChildrens(List<ShUserRole> shPropertyRoles, Long parentId) {
        List<ShUserRole> trs = new ArrayList<ShUserRole>();
        for (ShUserRole shUserRole : shPropertyRoles) {
            if (parentId == shUserRole.getParentId()) {
                trs.add(shUserRole);
                trs.addAll(queryAllChildrens(shPropertyRoles, shUserRole.getId()));
            }
        }
        return trs;
    }

	/* (non-Javadoc)
	 * @see com.smarthome.core.user.UserRoleService#UserRoleRootByResidenceId(java.lang.Long)
	 */
	@Override
	public ShUserRole UserRoleRootByResidenceId(Long residenceId) {
		if(residenceId == null)  return null;
		
		
		return shUserRoleService.queryUserRoleRootByResidenceId(residenceId);
	}

	/* (non-Javadoc)
	 */
	@Override
	public List<ShUserRole> shUserRolesByResidenceId(Long residenceId) {
		
		return shUserRoleService.queryShUserRolesByResidenceId(residenceId);
	}

	/* (non-Javadoc)
	 * @see com.smarthome.core.user.UserRoleService#treeByResidenceId(java.lang.Long)
	 */
	@Override
	public List<Tree> treeByResidenceId(Long residenceId) {
		List<ShUserRole> roles = shUserRoleService.queryShUserRolesByResidenceId(residenceId);
		List<Tree> trees = new ArrayList<Tree>();
		if(null == roles){
			return trees;
		}
		
		for(ShUserRole role : roles){
			trees.add(new Tree(role.getId(),role.getName(),role.getParentId(),role));
		}
		
		return TreeUtil.converttree(trees, 0l);
	}

	/* (non-Javadoc)
	 * @see com.smarthome.core.user.UserRoleService#isRepeat(com.smarthome.domain.bean.ShUserRole)
	 */
	@Override
	public boolean isRepeat(ShUserRole role) {
		if(null == role) return false;
		
		ShUserRole qr = new ShUserRole();
		qr.setName(role.getName());
		qr.setParentId(role.getParentId());
		List<ShUserRole> roles =  shUserRoleService.selectEntryList(qr);
	
		if(roles == null || roles.size() == 0){
			return false;
		}
		

		for(ShUserRole r : roles){
			if((r.getName() == null  && role.getName() == null)||role.getName().equals(r.getName())  ){
				if(role.getId() != null && r.getId().equals(role.getId())) continue;
				return true;
			}
		}
		
		return false;
		
	}
}
